import AppKit
import AVFoundation
import AVKit
import ScreenSaver

class DisplayManager {
    static let shared = DisplayManager()
    
    struct WallpaperState {
        var window: NSWindow?
        var player: AVPlayer?
        var isVideo: Bool
        var isPaused: Bool
        var volume: Float
        var isMuted: Bool
    }
    
    private var displayWallpapers: [NSScreen: WallpaperState] = [:]
    private let defaultWallpaperURL = Bundle.main.url(forResource: "default", withExtension: "jpg")
    
    private init() {}
    
    func setWallpaper(url: URL, isVideo: Bool, for screen: NSScreen) throws {
        if let existingState = displayWallpapers[screen], existingState.isVideo {
            try resetWallpaper(for: screen)
        }
        
        if isVideo {
            let player = AVPlayer(url: url)
            player.volume = 1.0
            
            let window = NSWindow(
                contentRect: screen.frame,
                styleMask: .borderless,
                backing: .buffered,
                defer: false
            )
            window.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.desktopWindow)))
            window.collectionBehavior = [.stationary, .ignoresCycle]
            
            let playerView = AVPlayerView()
            playerView.player = player
            playerView.controlsStyle = .none
            window.contentView = playerView
            
            window.orderFront(nil)
            player.play()
            
            displayWallpapers[screen] = WallpaperState(
                window: window,
                player: player,
                isVideo: true,
                isPaused: false,
                volume: 1.0,
                isMuted: false
            )
            
            NotificationCenter.default.addObserver(
                self,
                selector: #selector(playerItemDidReachEnd),
                name: .AVPlayerItemDidPlayToEndTime,
                object: player.currentItem
            )
        } else {
            try NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: [:])
            displayWallpapers[screen] = WallpaperState(
                window: nil,
                player: nil,
                isVideo: false,
                isPaused: false,
                volume: 1.0,
                isMuted: false
            )
        }
    }
    
    func resetWallpaper(for screen: NSScreen) throws {
        if let state = displayWallpapers[screen], state.isVideo {
            state.player?.pause()
            NotificationCenter.default.removeObserver(
                self,
                name: .AVPlayerItemDidPlayToEndTime,
                object: state.player?.currentItem
            )
            
            state.window?.orderOut(nil)
            state.window?.close()
            state.player?.replaceCurrentItem(with: nil)
            
            displayWallpapers.removeValue(forKey: screen)
        }
        
        if let url = defaultWallpaperURL {
            try setWallpaper(url: url, isVideo: false, for: screen)
        } else {
            throw NSError(
                domain: "DisplayManager",
                code: 1003,
                userInfo: [NSLocalizedDescriptionKey: "无法获取默认壁纸"]
            )
        }
    }
    
    func togglePlayPause(for screen: NSScreen) {
        guard let state = displayWallpapers[screen], state.isVideo else { return }
        if state.isPaused {
            state.player?.play()
        } else {
            state.player?.pause()
        }
        displayWallpapers[screen]?.isPaused.toggle()
    }
    
    func setVolume(_ volume: Float, for screen: NSScreen) {
        guard let state = displayWallpapers[screen], state.isVideo else { return }
        displayWallpapers[screen]?.volume = max(0, min(1, volume))
        state.player?.volume = state.isMuted ? 0 : state.volume
    }
    
    func toggleMute(for screen: NSScreen) {
        guard let state = displayWallpapers[screen], state.isVideo else { return }
        displayWallpapers[screen]?.isMuted.toggle()
        state.player?.volume = state.isMuted ? 0 : state.volume
        NotificationCenter.default.post(name: .muteStateChanged, object: nil)
    }
    
    func getWallpaperState(for screen: NSScreen) -> WallpaperState? {
        return displayWallpapers[screen]
    }
    
    @objc private func playerItemDidReachEnd(notification: Notification) {
        guard let playerItem = notification.object as? AVPlayerItem,
              let (_, state) = displayWallpapers.first(where: { $0.value.player?.currentItem === playerItem }) else {
            return
        }
        
        playerItem.seek(to: .zero, completionHandler: nil)
        if !state.isPaused {
            state.player?.play()
        }
    }
}
